package com.wiqer.job58;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.concurrent.ConcurrentSkipListMap;

//代理类模板，Proxy
/*方法名为空，先找run方法，再找@注解*/
public class ExpectTaskProxy<T>  implements InvocationHandler, MethodInterceptor {

    private Class<T> clazz;
    private ExpectTask task;
    private TaskContext taskContext;

    public ExpectTaskProxy(Class<T> clazz,  ExpectTask task){
        this.clazz = clazz;
        this.task = task;
    }

    //当前任务的主方法，可能没有用
    public void run(){

    }
    //启动方法
    public void start(){
       // Object a=ExpectTask.run;
    }
    //运行下一个任务
    public void runNext(){

        //1，根据nextExpectTask ，反射获取方法run
        //2，根据反射结果获取输入参数或者类型等信息
        //3，匹配到方法，转型？
        //4，将入参填充到下一个任务的params中
        //5,params到达预期后执行
        //
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class == method.getDeclaringClass()) {
            String name = method.getName();
            if ("equals".equals(name)) {
                return proxy == args[0];
            } else if ("hashCode".equals(name)) {
                return System.identityHashCode(proxy);
            } else if ("toString".equals(name)) {
                return proxy.getClass().getName() + "@" +
                        Integer.toHexString(System.identityHashCode(proxy)) +
                        ", with InvocationHandler " + this;
            } else {
                throw new IllegalStateException(String.valueOf(method));
            }
        }

        //0,运行比对方法是否是标记的方法，运行当前方法
        //1，根据nextExpectTask ，反射获取方法run
        //2，根据反射结果获取输入参数或者类型等信息
        //3，匹配到方法，转型？
        //4，将入参填充到下一个任务的params中
        //5,params到达预期后执行
        //
        return null;
    }
    public static Object reflectionMethod(Object object ,String methodName, Object... args) {

        try {

            Method[] methods = object.getClass().getMethods();
            Method method=null;
            for (Method m:methods){
                if(m.getName().contains(methodName)){
                    method=m;
                }
            }
            return method.invoke(object,args);


        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;

    }
    private Class<?> getClassType(Object obj) {

        Class<?> classType = obj.getClass();
//        String typeName = classType.getName();
//        switch (typeName) {
//            case "java.lang.Integer":
//                return Integer.TYPE;
//            case "java.lang.Long":
//                return Long.TYPE;
//            case "java.lang.Float":
//                return Float.TYPE;
//            case "java.lang.Double":
//                return Double.TYPE;
//            case "java.lang.Character":
//                return Character.TYPE;
//            case "java.lang.Boolean":
//                return Boolean.TYPE;
//            case "java.lang.Short":
//                return Short.TYPE;
//            case "java.lang.Byte":
//                return Byte.TYPE;
//        }
        return classType;
    }

    /**
     *
     * @param o 元对象
     * @param method 方法
     * @param objects 入参
     * @param methodProxy 未知，代理方法吗
     * @return
     * @throws Throwable
     */
    /**
     * 重写方法拦截在方法前和方法后加入业务
     * Object obj为目标对象
     * Method method为目标方法
     * Object[] params 为参数，
     * MethodProxy proxy CGlib方法代理对象
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] params,
                            MethodProxy proxy) throws Throwable {
        System.out.println("调用前");
        Object result = proxy.invokeSuper(obj, params);
        System.out.println(" 调用后:"+result);
        return result;
    }

    public ExpectTask getTask() {
        return task;
    }

    public void setTask(ExpectTask task) {
        this.task = task;
    }
}
